/*
 * 牛牛算法
 */
let gameProto = require('./gameProto');
let util = require('../../util/utils');
let handCards_Data = [
	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
	0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d
];

class GameLogic {
	constructor() {
		this.cards = [];
		this.cardsType = null;
		this.scaleType = null;
	}

	/*
	 * 洗牌
	 */
	washCards(gameType) {
		this.cards = [
			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
			0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
			0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
			0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d
		];
		if (gameType == gameProto.ruffianType.WANGLAI) {
			this.cards = [
				0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, // 方块A-K
				0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, // 梅花A-K
				0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, // 红桃A-K
				0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, // 黑桃A-K
				0x4E, 0x4F, //王牌
			];
		}
		for (let i = 0; i < this.cards.length; ++i) {
			let random = Math.floor(Math.random() * this.cards.length);
			let tmp = this.cards[i];
			this.cards[i] = this.cards[random];
			this.cards[random] = tmp;
		}
	}
	//获取卡牌
	getExceptCards(ruffianType) {
		let cards = [
			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
			0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
			0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
			0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d
		];
		if (ruffianType == gameProto.ruffianType.WANGLAI) {
			cards = [
				0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, // 方块A-K
				0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, // 梅花A-K
				0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, // 红桃A-K
				0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, // 黑桃A-K
				0x4E, 0x4F, //王牌
			];
		}
		return cards
	}

	getAllCardList(ruffianType, laiCard, SubstratumTradeCards) {

		let cards = [
			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
			0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
			0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
			0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d
		];
		//清理换牌数据
		let testCards = [];
		let cardsList = [];
		let isSubstratum = false;
		for (let i = 0; i < 10; i++) {
			cardsList[i] = [];
		}
		for (let key in SubstratumTradeCards) {

			if (SubstratumTradeCards[key] && SubstratumTradeCards[key].Cards && SubstratumTradeCards[key].Cards.length > 0) {
				isSubstratum = true;
				testCards = testCards.concat(SubstratumTradeCards[key].Cards);
				cardsList[SubstratumTradeCards[key].chairID] = SubstratumTradeCards[key].Cards.slice();
			}
		}
		cards = cards.filter(item => !testCards.includes(item));
		for (let i = 0; i < cards.length; ++i) {
			let random = Math.floor(Math.random() * cards.length);
			let tmp = cards[i];
			cards[i] = cards[random];
			cards[random] = tmp;
		}
		if (ruffianType == gameProto.ruffianType.WANGLAI) {
			for (let i = 0; i < 10; i++) {
				if (cardsList[i].length > 0) {
					continue;
				}
				cardsList[i] = cards.splice(0, 5);
			}
			if (!isSubstratum) {
				let getRandomNum = util.getRandomNum(0, 4);
				cardsList[0][getRandomNum] = 0x4E;
				getRandomNum = util.getRandomNum(0, 4);
				cardsList[1][getRandomNum] = 0x4F;

				//替换后随机洗牌
				for (let i = 0; i < cardsList.length; i++) {
					for (let index = 0; index < cardsList[i].length; index++) {
						let random_zi = Math.floor(Math.random() * cardsList[i].length);
						let tmp_zi = cardsList[i][index];
						cardsList[i][index] = cardsList[i][random_zi];
						cardsList[i][random_zi] = tmp_zi;
					}
					let random = Math.floor(Math.random() * cardsList.length);
					let tmp = cardsList[i];
					cardsList[i] = cardsList[random];
					cardsList[random] = tmp;
				}
			}
			return cardsList.slice();
		} else if (ruffianType == gameProto.ruffianType.SHUIJILAI) {

			//随机癞子
			let allCards = cards.filter(item => this.getCardNumber(item) != this.getCardNumber(laiCard));
			let laiList = cards.filter(item => this.getCardNumber(item) == this.getCardNumber(laiCard));
			for (let i = 0; i < 10; i++) {
				if (cardsList[i].length > 0) {
					continue;
				}
				if (i < 4) {
					let curList = allCards.splice(0, 4);
					curList.push(laiList.pop())
					cardsList[i] = curList.slice();
					for (let index = 0; index < cardsList[i].length; index++) {
						let random_zi = Math.floor(Math.random() * cardsList[i].length);
						let tmp_zi = cardsList[i][index];
						cardsList[i][index] = cardsList[i][random_zi];
						cardsList[i][random_zi] = tmp_zi;
					}
				} else {
					cardsList[i] = allCards.splice(0, 5);
				}
			}
			if (!isSubstratum) {
				for (let i = 0; i < cardsList.length; i++) {
					let random = Math.floor(Math.random() * cardsList.length);
					let tmp = cardsList[i];
					cardsList[i] = cardsList[random];
					cardsList[random] = tmp;
				}
			}
			return cardsList.slice();
		} else {
			//没有癞子的情况
			for (let i = 0; i < 10; i++) {
				if (cardsList[i].length > 0) {
					continue;
				}
				cardsList[i] = cards.splice(0, 5);
			}
			return cardsList.slice();
		}
	}


	/*
	 * 设置允许的牌类型
	 * @param Array cardsType 只能在此类型中
	 */
	setCardsType(cardsType, scaleType) {
		this.cardsType = cardsType;
		this.scaleType = scaleType;
	}

	getCardValueArr(cardDataArr) {
		let arr = [];
		for (let i = 0; i < cardDataArr.length; ++i) {
			arr.push(cardDataArr[i] & 0x0F);
		}
		arr.sort(function (a, b) {
			return (a - b)
		});
		return arr;
	};
	/*
	 * 获取牌的花色
	 * @param card 牌id
	 * @return Number 花色值
	 */
	getCardColor(card) {
		return Math.floor(card / 16);
	}

	/*
	 * 获取牌的花色名字
	 * @param card Number 牌id
	 * @return String 花色
	 */
	getCardColorName(card) {
		let colors = ['方块', '草花', '红桃', '黑桃'];
		if (card >= 0x01 && card <= 0x3d) {
			return colors[Math.floor(card / 0x10)];
		}
		return null;
	}

	/*
	 * 获取牌的计算值
	 * @param card Number 牌id
	 * @return Number 值
	 */
	getCardValue(card) {
		let value = card & 0x0f;
		if (value > 10) {
			value = 10;
		}
		return value;
	}

	/*
	 * 获取牌的牌面数值
	 * @param card Number 牌id
	 * @return Number 值
	 */
	getCardNumber(card) {
		return card & 0x0f;
	}

	/*
	 * 获取5张手牌
	 * @return Array 手牌
	 */
	getCards() {
		let cards = [];
		for (let i = 0; i < 5; ++i) {
			cards.push(this.cards.pop());
		}
		return cards;
	}

	/*
	 * 获取牌的类型  必须先设置可获取的类型 setCardsType
	 * @param cards Array 牌
	 * @return Number 类型
	 */
	getCardsType(cards) {
		if (!cards) {
			return;
		}
		let sum = 0;
		for (let i = 0; i < cards.length; ++i) {
			sum += this.getCardValue(cards[i]);
		}
		let niu_num = this.getNiuNumber(cards);

		let is_shunziniu = false; /* 顺子牛判断 */
		let array = cards.slice().sort((a, b) => {
			return this.getCardNumber(a) - this.getCardNumber(b);
		});
		let step_num = 0;
		for (let i = 1; i < array.length; ++i) {
			if (this.getCardNumber(array[i]) - 1 == this.getCardNumber(array[i - 1])) {
				++step_num;
			}
		}
		if (step_num == 4) {
			is_shunziniu = true;
		}
		if (this.getCardNumber(array[0]) == 1 &&
			this.getCardNumber(array[1]) == 10 &&
			this.getCardNumber(array[2]) == 11 &&
			this.getCardNumber(array[3]) == 12 &&
			this.getCardNumber(array[4]) == 13) {
			is_shunziniu = true;
		}

		let is_tonghuaniu = /* 同花牛判断 */
			this.getCardColor(cards[0]) == this.getCardColor(cards[1]) &&
			this.getCardColor(cards[1]) == this.getCardColor(cards[2]) &&
			this.getCardColor(cards[2]) == this.getCardColor(cards[3]) &&
			this.getCardColor(cards[3]) == this.getCardColor(cards[4]);

		let is_tonghuashunniu = is_shunziniu && is_tonghuaniu; /* 同花顺牛判断 */
		if (is_tonghuashunniu && this.cardsType && (!!this.cardsType.TONGHUASHUN)) {
			return this.getBiggerScale(gameProto.cardsType.TONGHUASHUN, niu_num);
		}

		let is_yitiaolongniu = is_shunziniu && this.getCardNumber(array[0]) == 1 && this.getCardNumber(array[1]) == 2; /* 一条龙牛判断 */
		if (is_yitiaolongniu && this.cardsType && !!this.cardsType.YITIAOLONG) {
			return this.getBiggerScale(gameProto.cardsType.YITIAOLONG, niu_num);
		}

		let four_same = false,
			three_same = false,
			two_same = false;
		for (let i = 0; i < cards.length; ++i) {
			let same = 0;
			for (let j = 0; j < cards.length; ++j) {
				if (this.getCardNumber(cards[i]) == this.getCardNumber(cards[j])) {
					++same;
				}
			}
			if (same == 4) {
				four_same = true;
			} else if (same == 3) {
				three_same = true;
			} else if (same == 2) {
				two_same = true;
			}
		}
		let is_zhadanniu = four_same; /* 炸弹牛判断 */
		if (is_zhadanniu && this.cardsType && !!this.cardsType.ZHADANNIU) {
			return this.getBiggerScale(gameProto.cardsType.ZHADANNIU, niu_num);
		}

		let is_wuxiaoniu = true; /* 五小牛判断 */
		for (let i = 0; i < cards.length; ++i) {
			if (this.getCardNumber(cards[i]) >= 5) {
				is_wuxiaoniu = false;
			}
		}
		is_wuxiaoniu = is_wuxiaoniu && (sum <= 10);
		if (is_wuxiaoniu && this.cardsType && !!this.cardsType.WUXIAONIU) {
			return this.getBiggerScale(gameProto.cardsType.WUXIAONIU, niu_num);
		}

		let is_huluniu = three_same && two_same; /* 葫芦牛判断 */
		if (is_huluniu && this.cardsType && !!this.cardsType.HULUNIU) {
			return this.getBiggerScale(gameProto.cardsType.HULUNIU, niu_num);
		}

		let is_wuhuaniu = true; /* 五花牛判断 */
		for (let i = 0; i < cards.length; ++i) {
			if ((cards[i] & 0x0f) <= 10) {
				is_wuhuaniu = false;
			}
		}
		if (is_wuhuaniu && this.cardsType && !!this.cardsType.WUHUANIU) {
			return this.getBiggerScale(gameProto.cardsType.WUHUANIU, niu_num);
		}

		if (is_tonghuaniu && this.cardsType && !!this.cardsType.TONGHUANIU) {
			return this.getBiggerScale(gameProto.cardsType.TONGHUANIU, niu_num);
		}

		let is_yinniu = /* 银牛判断 */
			this.getCardNumber(cards[0]) >= 10 &&
			this.getCardNumber(cards[1]) >= 10 &&
			this.getCardNumber(cards[2]) >= 10 &&
			this.getCardNumber(cards[3]) >= 10 &&
			this.getCardNumber(cards[4]) >= 10;
		if (is_yinniu && this.cardsType && !!this.cardsType.YINNIU) {
			return this.getBiggerScale(gameProto.cardsType.YINNIU, niu_num);
		}

		if (is_shunziniu && this.cardsType && !!this.cardsType.SHUNZINIU) {
			return this.getBiggerScale(gameProto.cardsType.SHUNZINIU, niu_num);
		}

		if (niu_num == 10) {
			return gameProto.cardsType.NIUNIU;
		}
		if (niu_num > 0) {
			return gameProto.cardsType.YOUNIU;
		}
		return gameProto.cardsType.MEINIU;
	}
	/*
	 * 获取最大牌的类型
	 * @param cards Array 牌
	 * @param ruffianRecord int 癞子点数
	 * @return Number 类型
	 */
	GetMaxCardType(card, ruffianRecord) {
		let handCard = card.slice();
		//获取癞子数量
		let Sun_list = 0;
		//将癞子置空 保证癞子是第一个位置
		for (let i = 0; i < card.length; i++) {
			if (this.getCardNumber(card[i]) == 14 || this.getCardNumber(card[i]) == 15) {
				Sun_list++
			} else if (this.getCardNumber(card[i]) == ruffianRecord) {
				Sun_list++;
			}
		}
		let arr = card.slice();
		if (Sun_list == 1) {
			arr = this.GetOneCardType(handCard, ruffianRecord);
		} else if (Sun_list == 2) {
			arr = this.GetTwoCardType(handCard, ruffianRecord);
		} else if (Sun_list >= 3) {
			arr = this.GetThree_And_FourCardType(handCard, ruffianRecord);
		}
		if (!arr) {
			let a = 0;
		}
		return arr;
	}
	/*
	 * 获取1癞子牌型
	 * @param cards Array 牌
	 * @param ruffianRecord int 癞子点数
	 * @return Number 类型
	 */
	GetOneCardType(card, ruffianRecord) {
		//将癞子置空 保证癞子是第一个位置
		for (let i = 0; i < card.length; i++) {
			if (this.getCardNumber(card[i]) == 14 || this.getCardNumber(card[i]) == 15) {
				card[i] = 0;
			} else if (this.getCardNumber(card[i]) == ruffianRecord) {
				card[i] = 0;
			}
		}
		//排序
		card.sort(function (a, b) {
			return (a - b)
		});
		// this.cards.sort(function (a, b) {
		// 	return (a - b)
		// });
		//放入一个初始数据
		for (let i = 0; i < handCards_Data.length; i++) {
			//||this.getCardNumber(handCards_Data[i]) == ruffianRecord
			if (handCards_Data[i] == 0x4E || handCards_Data[i] == 0x4F || handCards_Data[i] == card[1] || handCards_Data[i] == card[2] || handCards_Data[i] == card[3] || handCards_Data[i] == card[4]) {
				continue;
			}
			card[0] = handCards_Data[i];
			break;
		}
		//构造二次数据
		let NextCard = [0, 0, 0, 0, 0];
		NextCard[1] = card[1];
		NextCard[2] = card[2];
		NextCard[3] = card[3];
		NextCard[4] = card[4];
		for (let i = 0; i < handCards_Data.length; i++) {
			//||this.getCardNumber(handCards_Data[i]) == ruffianRecord
			if (handCards_Data[i] == 0x4E || handCards_Data[i] == 0x4F || handCards_Data[i] == NextCard[1] || handCards_Data[i] == NextCard[2] || handCards_Data[i] == NextCard[3] || handCards_Data[i] == NextCard[4]) {
				continue;
			}
			NextCard[0] = handCards_Data[i];
			//比较牌型
			let maxCardType = this.getCardsType(card);
			let nextCardType = this.getCardsType(NextCard);
			//比较牛牛大小
			let maxgetScale = this.getNiuNumber(card);
			let nextgetScale = this.getNiuNumber(NextCard);

			if ((nextCardType > maxCardType) || (nextCardType >= maxCardType && nextgetScale >= maxgetScale)) {
				card[0] = handCards_Data[i];
			}
		}
		//返回一个最高的数据
		return card;
	}
	/*
	 * 获取2癞子牌型
	 * @param cards Array 牌
	 * @param ruffianRecord int 癞子点数
	 * @return Number 类型
	 */
	GetTwoCardType(card, ruffianRecord) {
		let handCard = card.slice();
		//将癞子置空 保证癞子是第一个位置
		for (let i = 0; i < handCard.length; i++) {
			if (this.getCardNumber(handCard[i]) == 14 || this.getCardNumber(handCard[i]) == 15) {
				handCard[i] = 0;
			} else if (this.getCardNumber(handCard[i]) == ruffianRecord) {
				handCard[i] = 0;
			}
		}
		//排序
		handCard.sort(function (a, b) {
			return (a - b)
		});
		// this.cards.sort(function (a, b) {
		// 	return (a - b)
		// });
		//第一位放入一个初始数据
		if (handCard[0] == 0 && handCard[1] == [0]) {
			//构比较数据
			let NextCard = card.slice();
			for (let i = 0; i < handCards_Data.length; i++) {
				if (handCards_Data[i] == 0x4E || handCards_Data[i] == 0x4F || handCards_Data[i] == handCard[2] || handCards_Data[i] == handCard[3] || handCards_Data[i] == handCard[4]) {
					continue;
				}
				handCard[0] = handCards_Data[i];

				for (let j = 0; j < handCards_Data.length; j++) {
					if (handCards_Data[i] == 0x4E || handCards_Data[i] == 0x4F || handCards_Data[i] == handCard[2] || handCards_Data[i] == handCard[3] || handCards_Data[i] == handCard[4]) {
						continue;
					}
					handCard[1] = handCards_Data[j];

					//比较牌型
					let maxCardType = this.getCardsType(handCard);
					let nextCardType = this.getCardsType(NextCard);
					//比较牛牛大小
					let maxgetScale = this.getNiuNumber(handCard);
					let nextgetScale = this.getNiuNumber(NextCard);

					if (maxCardType >= nextCardType || (maxCardType >= nextCardType && maxgetScale >= nextgetScale)) {
						NextCard = handCard.slice();
					}
				}
			}
			//返回一个最高的数据
			return NextCard;
		}
		return false;
	}

	/*
	 * 获取3.4癞子牌型
	 * @param cards Array 牌
	 * @param ruffianRecord int 癞子点数
	 * @return Number 类型
	 */
	GetThree_And_FourCardType(card, ruffianRecord) {
		let handCard = card.slice();
		//将癞子置空 保证癞子是第一个位置
		let Sun_list = 0;
		for (let i = 0; i < handCard.length; i++) {
			if (this.getCardNumber(handCard[i]) == 14 || this.getCardNumber(handCard[i]) == 15) {
				handCard[i] = 0;
				Sun_list++;
			} else if (this.getCardNumber(handCard[i]) == ruffianRecord) {
				handCard[i] = 0;
				Sun_list++;
			}
		}
		//排序
		handCard.sort(function (a, b) {
			return (a - b)
		});
		if (Sun_list == 4 || Sun_list == 3) {
			let Replacement = this.ReplacementData(handCard, Sun_list, ruffianRecord);
			if (Replacement) {
				return Replacement;
			}
		}
		return false;
	}
	ReplacementColorName(Card) {
		let handCard_Color = [];
		let handC = handCards_Data.slice();
		if (Card == 0) {
			handCard_Color = handC.splice(0, 12);
		} else if (Card == 1) {
			handCard_Color = handC.splice(13, 25);
		} else if (Card == 2) {
			handCard_Color = handC.splice(26, 38);
		} else if (Card == 3) {
			handCard_Color = handC.splice(39, 51);
		}
		return handCard_Color;
	}
	ReplacementData(Card, Sun_list, ruffianRecord) {
		let handCard = [];
		if (this.cardsType && (!!this.cardsType.TONGHUASHUN || !!this.cardsType.YITIAOLONG || !!this.cardsType.SHUNZINIU)) {
			handCard = this.TONGHUASHUNData(Card, Sun_list);
			if (handCard) {
				return handCard;
			}

		}
		if (this.cardsType && !!this.cardsType.ZHADANNIU) {
			if (Sun_list == 4) {
				handCard = [Card[4], Card[4], Card[4], Card[4], Card[4]];
				return handCard;
			} else if (Sun_list == 3) {
				handCard = [Card[4], Card[4], Card[4], Card[4], Card[3]];
				return handCard;
			}
		}
		if (this.cardsType && !!this.cardsType.WUXIAONIU) {
			handCard = this.WUXIAONIUData(Card, Sun_list);
			if (handCard) {
				return handCard;
			}
		}
		if (this.cardsType && !!this.cardsType.HULUNIU) {
			handCard = this.HULUNIUData(Card, Sun_list);
			if (handCard) {
				return handCard;
			}
		}
		if (this.cardsType && !!this.cardsType.WUHUANIU) {
			handCard = this.WUHUANIUData(Card, Sun_list);
			if (handCard) {
				return handCard;
			}
		}
		if (this.cardsType && !!this.cardsType.TONGHUANIU) {
			handCard = this.TONGHUANIUData(Card, Sun_list);
			if (handCard) {
				return handCard;
			}
		}
		if (this.cardsType && !!this.cardsType.YINNIU) {
			handCard = this.WUHUANIUData(Card, Sun_list);
			if (handCard) {
				return handCard;
			}
		}
		if (this.cardsType && !!this.cardsType.NIUNIU) {
			handCard = this.NIUNIUData(Card, Sun_list, ruffianRecord);
			if (handCard) {
				return handCard;
			}
		}
	}
	TONGHUASHUNData(Card, Sun_list) {
		let handCard_One_Card = this.getCardNumber(Card[4]);
		let handCard_Three_Card = this.getCardNumber(Card[3]);
		let handCard_One_Color = this.ReplacementColorName(this.getCardColor(Card[4]));
		let handCard_Three_Color = this.ReplacementColorName(this.getCardColor(Card[3]));
		let handCard = [0, 0, 0, 0, 0];
		if (Sun_list == 4) {
			if (handCard_One_Card + 1 == 13) //Q
			{
				handCard[0] = handCard_One_Color[handCard_One_Card + 1 - 1]; //K
				handCard[1] = handCard_One_Color[handCard_One_Card - 1 - 1]; //J
				handCard[2] = handCard_One_Color[handCard_One_Card - 2 - 1]; //10
				handCard[3] = handCard_One_Color[0]; //A
			} else if (handCard_One_Card + 2 == 13) //J
			{
				handCard[0] = handCard_One_Color[handCard_One_Card + 2 - 1]; //K
				handCard[1] = handCard_One_Color[handCard_One_Card + 1 - 1]; //Q
				handCard[2] = handCard_One_Color[handCard_One_Card - 1 - 1]; //10
				handCard[3] = handCard_One_Color[0]; //A
			} else if (handCard_One_Card + 3 == 13) //10
			{
				handCard[0] = handCard_One_Color[handCard_One_Card + 3 - 1]; //K
				handCard[1] = handCard_One_Color[handCard_One_Card + 2 - 1]; //Q
				handCard[2] = handCard_One_Color[handCard_One_Card + 1 - 1]; //J
				handCard[3] = handCard_One_Color[0]; //A
			} else if (handCard_One_Card == 13) //K
			{
				handCard[0] = handCard_One_Color[handCard_One_Card - 3 - 1]; //Q
				handCard[1] = handCard_One_Color[handCard_One_Card - 2 - 1]; //J
				handCard[2] = handCard_One_Color[handCard_One_Card - 1 - 1]; //10
				handCard[3] = handCard_One_Color[0]; //A
			} else {
				handCard[0] = handCard_One_Color[handCard_One_Card + 4 - 1];
				handCard[1] = handCard_One_Color[handCard_One_Card + 3 - 1];
				handCard[2] = handCard_One_Color[handCard_One_Card + 2 - 1];
				handCard[3] = handCard_One_Color[handCard_One_Card + 1 - 1];
			}
			handCard[4] = Card[4];
			return handCard;
		} else if (Sun_list == 3) {
			if (handCard_Three_Card + 4 >= handCard_One_Card) {
				handCard[0] = Card[3];
				for (let i = 1; i < 5; i++) {
					if (handCard_Three_Card + i == handCard_One_Card) {
						handCard[i] = Card[4];
						continue;
					}
					if (handCard_Three_Card + i >= 13) {
						handCard[i] = handCard_Three_Color[i];
					} else {
						handCard[i] = handCard_Three_Color[handCard_Three_Card + i - 1];
					}
				}
				return handCard;
			}
		}
	}
	WUXIAONIUData(Card, Sun_list) {
		let handCard_One_Card = this.getCardNumber(Card[4]);
		let handCard_Three_Card = this.getCardNumber(Card[3]);
		let handCard_One_Color = this.ReplacementColorName(this.getCardColor(Card[4]));
		let handCard_Three_Color = this.ReplacementColorName(this.getCardColor(Card[3]));
		let handCard = [0, 0, 0, 0, 0];
		if (Sun_list == 4) {
			if (handCard_One_Card >= 5) {
				return false;
			}
			handCard = [Card[4], Card[4], Card[4], Card[4], Card[4]];
			return handCard;
		} else if (Sun_list == 3) {
			if (handCard_One_Card >= 5 || handCard_Three_Card >= 5) {
				return false;
			}
			handCard = [Card[3], Card[3], Card[3], Card[3], Card[4]];
			return handCard;
		}

	}
	HULUNIUData(Card, Sun_list) {
		let handCard_One_Card = this.getCardNumber(Card[4]);
		let handCard_Three_Card = this.getCardNumber(Card[3]);
		let handCard = [0, 0, 0, 0, 0];
		if (Sun_list == 4) {
			if (Card[4] == 0x3D) //A
			{
				handCard[0] = Card[4];
				handCard[1] = Card[4];
				handCard[2] = 0x31; //A
				handCard[3] = 0x31; //A
			} else {
				handCard[0] = 0x3D; //k
				handCard[1] = 0x3D; //k
				handCard[2] = 0x3D; //k
				handCard[3] = Card[4];
			}
			handCard[4] = Card[4];
			return handCard;
		} else if (Sun_list == 3) {
			if (handCard_One_Card == handCard_Three_Card && Card[4] == 0x3D) {
				handCard[0] = Card[4];
				handCard[1] = Card[4];
				handCard[2] = Card[3];
				handCard[3] = 0x31; //A
				handCard[4] = 0x31; //A
			} else if (handCard_One_Card == handCard_Three_Card) {
				handCard[0] = 0x3D; //k
				handCard[1] = 0x3D; //k
				handCard[2] = 0x3D; //k
				handCard[3] = Card[3];
				handCard[4] = Card[4];
			}

			if (Card[4] == 0x3D) //A
			{
				handCard[0] = Card[4];
				handCard[1] = Card[4];
				handCard[2] = Card[4];
				handCard[3] = Card[3];
				handCard[4] = Card[3];
			} else {
				handCard[0] = Card[4];
				handCard[1] = Card[4];
				handCard[2] = Card[4];
				handCard[3] = Card[3];
				handCard[4] = Card[3];
			}

			return handCard;
		}

	}
	WUHUANIUData(Card, Sun_list) {
		let handCard_One_Card = this.getCardNumber(Card[4]);
		let handCard_Three_Card = this.getCardNumber(Card[3]);
		let handCard_One_Color = this.ReplacementColorName(this.getCardColor(Card[4]));
		let handCard_Three_Color = this.ReplacementColorName(this.getCardColor(Card[3]));
		let handCard = [0, 0, 0, 0, 0];
		if (Sun_list == 4) {
			if (handCard_One_Card <= 10) {
				return false;
			}
			handCard[0] = Card[4];
			handCard[1] = Card[4];
			handCard[2] = Card[4];
			handCard[3] = Card[4];
			handCard[4] = Card[4];
			return handCard;
		} else if (Sun_list == 3) {
			if (handCard_One_Card <= 10 || handCard_Three_Card <= 10) {
				return false;
			}
			handCard[0] = Card[4];
			handCard[1] = Card[4];
			handCard[2] = Card[4];
			handCard[3] = Card[3];
			handCard[4] = Card[3];
			return handCard;

		}
	}
	TONGHUANIUData(Card, Sun_list) {
		let handCard_One_Color = this.ReplacementColorName(this.getCardColor(Card[4]));
		let handCard = [0, 0, 0, 0, 0];
		if (Sun_list == 4) {
			handCard[0] = handCard_One_Color[0];
			handCard[1] = handCard_One_Color[1];
			handCard[2] = handCard_One_Color[2];
			handCard[3] = handCard_One_Color[3];
			handCard[4] = Card[4];
			return handCard;
		} else if (Sun_list == 3) {
			if (this.getCardColor(Card[4]) != this.getCardColor(Card[3])) {
				return false;
			}
			handCard[0] = handCard_One_Color[0];
			handCard[1] = handCard_One_Color[1];
			handCard[2] = handCard_One_Color[2];
			handCard[3] = Card[4];
			handCard[4] = Card[4];
			return handCard;
		}
	}
	NIUNIUData(Card, Sun_list, ruffianRecord) {
		let handCard_One_Color = this.ReplacementColorName(this.getCardColor(Card[4]));
		let handCard = [0, 0, 0, 0, 0];
		if (Sun_list == 4) {
			handCard[0] = 0x3d;
			handCard[1] = 0x3d;
			handCard[2] = 0;
			handCard[3] = 0;
			handCard[4] = Card[4];
			let GetTwoCardType = this.GetTwoCardType(handCard, ruffianRecord);
			if (GetTwoCardType)
				return GetTwoCardType;
		} else if (Sun_list == 3) {
			handCard[0] = 0x3d;
			handCard[1] = 0x3d;
			handCard[2] = 0;
			handCard[3] = Card[3];
			handCard[4] = Card[4];
			let GetTwoCardType = this.GetOneCardType(handCard, ruffianRecord);
			if (GetTwoCardType)
				return GetTwoCardType;
		}
	}

	/*
	 * 比较两幅牌的大小，0和，1cards1大，-1cards2大
	 * @param cards1 Array 牌1
	 * @param cards2 Array 牌2
	 * @return Number 结果
	 */
	compareCards(cards1, cards2) {


		let type1 = this.getCardsType(cards1);
		let type2 = this.getCardsType(cards2);
		if (type1 != type2) {
			return type1 - type2;
		}
		if (type1 == gameProto.cardsType.YOUNIU) {
			let niu_num1 = this.getNiuNumber(cards1);
			let niu_num2 = this.getNiuNumber(cards2);
			if (niu_num1 != niu_num2) {
				return niu_num1 - niu_num2;
			}
		}
		let niu_num1 = cards1[0],
			niu_num2 = cards2[0]; /* 牌型相同时，需要比较的两张牌 */
		for (let i = 1; i < cards1.length; ++i) {
			if (this.getCardNumber(cards1[i]) > this.getCardNumber(niu_num1)) {
				niu_num1 = cards1[i];
			} else if (this.getCardNumber(cards1[i]) == this.getCardNumber(niu_num1) &&
				this.getCardColor(cards1[i]) > this.getCardColor(niu_num1)) {
				niu_num1 = cards1[i];
			}

			if (this.getCardNumber(cards2[i]) > this.getCardNumber(niu_num2)) {
				niu_num2 = cards2[i];
			} else if (this.getCardNumber(cards2[i]) == this.getCardNumber(niu_num2) &&
				this.getCardColor(cards2[i]) > this.getCardColor(niu_num2)) {
				niu_num2 = cards2[i];
			}
		}

		if (type1 == gameProto.cardsType.ZHADANNIU) {
			/* 炸弹牛比较炸弹 */
			for (let i = 1; i < cards1.length; ++i) {
				if (this.getCardNumber(cards1[i]) == this.getCardNumber(cards1[i - 1])) {
					niu_num1 = cards1[i];
				}
				if (this.getCardNumber(cards2[i]) == this.getCardNumber(cards2[i - 1])) {
					niu_num2 = cards2[i];
				}
			}
		} else if (type1 == gameProto.cardsType.HULUNIU) {
			/* 葫芦牛比较葫芦 */
			for (let i = 0; i < cards1.length; ++i) {
				let same1 = 0,
					same2 = 0;
				for (let j = 0; j < cards1.length; ++j) {
					if (this.getCardNumber(cards1[i]) == this.getCardNumber(cards1[j])) {
						++same1;
					}
					if (this.getCardNumber(cards2[i]) == this.getCardNumber(cards2[j])) {
						++same2;
					}
					if (same1 == 3) {
						niu_num1 = cards1[i];
					}
					if (same2 == 3) {
						niu_num2 = cards2[i];
					}
				}
			}
		}

		if (this.getCardNumber(niu_num1) != this.getCardNumber(niu_num2)) {
			return this.getCardNumber(niu_num1) - this.getCardNumber(niu_num2);
		} else {
			return this.getCardColor(niu_num1) - this.getCardColor(niu_num2);
		}
	}

	/*
	 * 根据牌型获取赔率
	 * @param Number type 类型
	 * @return Number 赔率
	 */
	getScaleByType(type) {
		if (type == gameProto.cardsType.MEINIU) {
			return 1;
		} else if (type == gameProto.cardsType.YOUNIU) {
			return 2;
		} else if (type == gameProto.cardsType.NIUNIU) {
			return 3;
		} else if (type == gameProto.cardsType.SHUNZINIU) {
			return (this.scaleType == gameProto.scaleType.DIANZI) ? 11 : 4;
		} else if (type == gameProto.cardsType.YINNIU) {
			return (this.scaleType == gameProto.scaleType.DIANZI) ? 11 : 4;
		} else if (type == gameProto.cardsType.TONGHUANIU) {
			return (this.scaleType == gameProto.scaleType.DIANZI) ? 11 : 6;
		} else if (type == gameProto.cardsType.WUHUANIU) {
			return (this.scaleType == gameProto.scaleType.DIANZI) ? 11 : 6;
		} else if (type == gameProto.cardsType.HULUNIU) {
			return (this.scaleType == gameProto.scaleType.DIANZI) ? 12 : 6;
		} else if (type == gameProto.cardsType.WUXIAONIU) {
			return (this.scaleType == gameProto.scaleType.DIANZI) ? 13 : 7;
		} else if (type == gameProto.cardsType.ZHADANNIU) {
			return (this.scaleType == gameProto.scaleType.DIANZI) ? 14 : 8;
		} else if (type == gameProto.cardsType.YITIAOLONG) {
			return (this.scaleType == gameProto.scaleType.DIANZI) ? 15 : 9;
		} else if (type == gameProto.cardsType.TONGHUASHUN) {
			return (this.scaleType == gameProto.scaleType.DIANZI) ? 16 : 10;
		}
	}

	/*
	 * 根据牌获取赔率
	 * @param cards Array 手牌
	 * @return Number 赔率
	 */
	getScaleByCards(cards) {
		let type = this.getCardsType(cards);
		let scale = this.getScaleByType(type);
		if (type == gameProto.cardsType.YOUNIU || type == gameProto.cardsType.NIUNIU) {
			let niu_num = this.getNiuNumber(cards);
			if (this.scaleType == gameProto.scaleType.BIG) {
				scale = [1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 4][niu_num];
			} else if (this.scaleType == gameProto.scaleType.LITTLE) {
				scale = [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3][niu_num];
			} else {
				scale = [1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10][niu_num];
			}
		}
		return scale;
	}

	/*
	 * 获取牛几类型
	 * @param Array cards 牌
	 * @return Number 牛0～10
	 */
	getNiuNumber(cards) {
		let sum = 0;
		for (let i = 0; i < cards.length; ++i) {
			sum += this.getCardValue(cards[i]);
		}
		let niu_num = 0;
		for (let i = 0; i < cards.length && niu_num == 0; ++i) {
			for (let j = i + 1; j < cards.length && niu_num == 0; ++j) {
				let rest = sum - this.getCardValue(cards[i]) - this.getCardValue(cards[j]);
				if (rest % 10 == 0) {
					/* 有牛 */
					niu_num = (sum - rest) % 10;
					if (niu_num == 0) {
						niu_num = 10;
					}
				}
			}
		}
		return niu_num;
	}

	/* 同点子牛类型比较，返回较大的类型 */
	getBiggerScale(type, niu_num) {
		if (this.scaleType == gameProto.scaleType.DIANZI) {
			let scale = this.getScaleByType(type);
			if (scale >= niu_num) {
				return type;
			} else {
				if (niu_num == 10) {
					return gameProto.cardsType.NIUNIU;
				} else {
					return gameProto.cardsType.YOUNIU;
				}
			}
		} else {
			return type;
		}
	}
}

module.exports = GameLogic;